/*
 * Copyright (C) Antonio Ramon Morcillo
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package soft.xitxarello.su.fragments;

import java.util.List;

import org.holoeverywhere.app.ListFragment;

import soft.xitxarello.su.R;
import soft.xitxarello.su.adapters.AppListAdapter;
import soft.xitxarello.su.data.App;
import soft.xitxarello.su.loaders.AppListLoader;
import org.holoeverywhere.app.Activity;
import android.os.Bundle;
import android.support.v4.content.Loader;
import android.view.View;
import android.widget.AdapterView;
import android.widget.TextView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import android.support.v4.app.LoaderManager;

/**
 * A fragment that displays a list of installed applications by binding to a
 * data source from Cursor, and exposes event handlers when the user selects an
 * item.
 * 
 * @see org.holoeverywhere.app.ListFragment
 * @see android.app.LoaderManager.LoaderCallbacks
 */
public class AppListFragment extends ListFragment implements
        LoaderManager.LoaderCallbacks<List<App>> {

    // Selected App Listener.
    private OnItemSelected mListener;

    // This is the Adapter being used to display the list.
    private AppListAdapter mAdapter;

    /**
     * Overrides a superclass method. Called when the fragment's activity has
     * been created and this fragment's view hierarchy instantiated.
     * 
     * @param savedInstanceState A mapping from String values to various
     *            Parcelable types.
     * @see com.actionbarsherlock.app.SherlockListFragment#onActivityCreated(Bundle
     *      savedInstanceState)
     */
    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        // Give some text to display if there is no data.
        setEmptyText(getString(R.string.no_apps));

        // Implements a list header.
        View header = getLayoutInflater(savedInstanceState)
                .inflate(R.layout.list_header, null);
        setListAdapter(null);
        ListView lv = getListView();
        ((TextView) header.findViewById(R.id.list_text_header)).setText(getActivity().getString(
                R.string.list_header));
        lv.addHeaderView(header);

        // Create an empty adapter we will use to display the loaded
        // applications.
        mAdapter = new AppListAdapter(getActivity());
        setListAdapter(mAdapter);

        // Add Listener for every application of the list.
        getListView().setOnItemClickListener(new OnItemClickListener() {
            public void onItemClick(AdapterView<?> parent, View v,
                    int position, long id) {

                // Send the event to the host activity via
                // OnItemSelected and the position 1 as first
                // because we don't count list header at 0 position.
                if (position > 0) {
                    mListener.onItemSelected((App) mAdapter.getItem(position - 1));
                }
            }
        });

        // Start out with a progress indicator.
        setListShown(false);

        // Prepare the loader. Either re-connect with an existing one,
        // or start a new one.
        getLoaderManager().initLoader(0, null, this);
    }

    /**
     * Overrides a superclass method. Instantiate and return a new Loader for
     * the given ID.
     * 
     * @param id The ID whose loader is to be created.
     * @param args Any arguments supplied by the caller.
     */
    @Override
    public Loader<List<App>> onCreateLoader(int id, Bundle args) {
        // This is called when a new Loader needs to be created. This
        // sample only has one Loader with no arguments, so it is simple.
        return new AppListLoader(getActivity());
    }

    /**
     * Overrides a superclass method. Called when a previously created loader
     * has finished its load.
     * 
     * @param loader The Loader that has finished.
     * @param data The data generated by the Loader, a list of uninstallable
     *            applications.
     */
    @Override
    public void onLoadFinished(Loader<List<App>> loader, List<App> data) {
        // Set the new data in the adapter.
        mAdapter.setData(data);

        // The list should now be shown.
        if (isResumed()) {
            setListShown(true);
        } else {
            setListShownNoAnimation(true);
        }
    }

    /**
     * Overrides a superclass method. Called when a previously created loader is
     * being reset, and thus making its data unavailable.
     * 
     * @param loader The Loader that is being reset.
     */
    @Override
    public void onLoaderReset(Loader<List<App>> loader) {
        // Clear the data in the adapter.
        mAdapter.setData(null);
    }

    /**
     * Container Activity must implement this interface.
     */
    public interface OnItemSelected {

        /**
         * Method for the Activity when an item has been selected.
         * 
         * @param app The Uninstallable Application Selected.
         */
        void onItemSelected(App app);
    }

    /**
     * Overrides a superclass method. Called when a fragment is first attached
     * to its activity. Activity must implement the interface OnItemSelected.
     * 
     * @param activity An activity is a single, focused thing that the user can
     *            do.
     */
    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);

        try {
            mListener = (OnItemSelected) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString()
                    + " must implement OnItemSelected");
        }
    }
}
